using System.Web;
using System.Security.Permissions;
using System.ComponentModel;
using System.Web.UI;
using System.Web.UI.WebControls;
using System;
using System.Globalization;
using System.Web.UI.HtmlControls;

namespace SharpPieces.Web.Controls
{

    /// <summary>
    /// Represents a tag cloud link field.
    /// </summary>
    [AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal), AspNetHostingPermission(SecurityAction.LinkDemand, Level = AspNetHostingPermissionLevel.Minimal)]
    public class TagCloudLinkField : TagCloudField
    {

        // Fields

        private DirtyFlags dirtyFlags = DirtyFlags.None;
        private string dataTextField;
        private string dataTextFormatString;
        private string dataUrlField;
        private string dataUrlFormatString;
        private string target;

        // Methods

        /// <summary>
        /// When implemented by a class, loads the server control's previously saved view state to the control.
        /// </summary>
        /// <param name="state">An <see cref="T:System.Object"></see> that contains the saved view state values for the control.</param>
        internal override void LoadViewState(object state)
        {
            if (null != state)
            {
                object[] s = state as object[];
                if (null != s[0])
                {
                    base.LoadViewState(s[0]);
                }
                if (null != s[1])
                {
                    this.DataTextField = (string)s[1];
                }
                if (null != s[2])
                {
                    this.DataTextFormatString = (string)s[2];
                }
                if (null != s[3])
                {
                    this.DataUrlField = (string)s[3];
                }
                if (null != s[4])
                {
                    this.DataUrlFormatString = (string)s[4];
                }
            }
        }

        /// <summary>
        /// When implemented by a class, saves the changes to a server control's view state to an <see cref="T:System.Object"></see>.
        /// </summary>
        /// <returns>
        /// The <see cref="T:System.Object"></see> that contains the view state changes.
        /// </returns>
        internal override object SaveViewState()
        {
            object[] state = new object[5];

            state[0] = base.SaveViewState();
            state[1] = ((this.dirtyFlags & DirtyFlags.DataTextField) == DirtyFlags.DataTextField) ? this.DataTextField : null;
            state[2] = ((this.dirtyFlags & DirtyFlags.DataTextFormatString) == DirtyFlags.DataTextFormatString) ? this.DataTextFormatString : null;
            state[3] = ((this.dirtyFlags & DirtyFlags.DataUrlField) == DirtyFlags.DataUrlField) ? this.DataUrlField : null;
            state[4] = ((this.dirtyFlags & DirtyFlags.DataUrlFormatString) == DirtyFlags.DataUrlFormatString) ? this.DataUrlFormatString : null;

            return state;
        }

        /// <summary>
        /// Formats one data value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="format">The value format.</param>
        /// <returns>The formated value.</returns>
        private string FormatOneDataValue(object value, string format)
        {
            if ((null == value) || Convert.IsDBNull(value))
            {
                return null;
            }

            if (string.IsNullOrEmpty(format))
            {
                return string.Format("{0}", value);
            }

            return string.Format(CultureInfo.CurrentCulture, format, new object[] { value });
        }

        /// <summary>
        /// Initializes this tag into the specified container.
        /// </summary>
        /// <param name="container">The container in which this tag is going to be initialized.</param>
        public virtual void Initialize(HtmlGenericControl container)
        {
            if (null == container)
            {
                throw new ArgumentNullException("container");
            }

            if (this.Visible)
            {
                HyperLink link = new HyperLink();
                link.Target = this.Target;

                if (!string.IsNullOrEmpty(this.DataTextField) || !string.IsNullOrEmpty(this.DataUrlField))
                {
                    link.DataBinding += new EventHandler(this.OnDataBindField);
                }

                container.Controls.Add(link);
            }
        }

        private void OnDataBindField(object sender, EventArgs e)
        {
            HyperLink link = sender as HyperLink;
            if (null == sender)
            {
                throw new ArgumentException("Invalid sender value. It can't be null.");
            }

            Control namingContainer = link.NamingContainer;
            if (null == namingContainer)
            {
                throw new HttpException("TagCloudLinkField can't be bound without a naming container.");
            }

            object component = DataBinder.GetDataItem(namingContainer);
            if (null == component)
            {
                throw new HttpException(string.Format("No data source defined for {0} to bind for TagCloudLinkField.", namingContainer));
            }

            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(component);

            if ("" != this.DataTextField)
            {
                PropertyDescriptor textFieldDesc = properties.Find(this.DataTextField, true);
                if (null == textFieldDesc)
                {
                    throw new HttpException(string.Format("Invalid DataTextField value. No property was found for this value."));
                }

                link.Text = this.FormatOneDataValue(textFieldDesc.GetValue(component), this.DataTextFormatString);
            }

            if ("" != this.DataUrlField)
            {
                PropertyDescriptor urlFieldDesc = properties.Find(this.DataUrlField, true);
                if (null == urlFieldDesc)
                {
                    throw new HttpException(string.Format("Invalid DataUrlField value. No property was found for this value."));
                }

                link.NavigateUrl = this.FormatOneDataValue(urlFieldDesc.GetValue(component), this.DataUrlFormatString);
            }

        }

        // Properties

        /// <summary>
        /// Gets or sets the name of the field from the data source containing the 
        /// text to display for the hyperlink captions in the TagCloudLinkField object. 
        /// </summary>
        /// <value>The name of the field from the data source containing the 
        /// text to display for the hyperlink captions.</value>
        [DefaultValue(null), Description("The name of the field from the data source containing the text to display for the hyperlink captions in the TagCloudLinkField object."), Category("Data")]
        public string DataTextField
        {
            get { return this.dataTextField; }
            set
            {
                if (this.dataTextField != value)
                {
                    this.dataTextField = value;
                    if ((this as IStateManager).IsTrackingViewState)
                    {
                        this.dirtyFlags = this.dirtyFlags | DirtyFlags.DataTextField;
                    }
                    this.OnFieldChanged();
                }
            }
        }

        /// <summary>
        /// Get or sets the string that specifies the format in which the hyperlink 
        /// captions in a TagCloudLinkField object are displayed. 
        /// </summary>
        /// <value>The string that specifies the format in which the hyperlink 
        /// captions.</value>
        [DefaultValue(null), Description("The string that specifies the format in which the hyperlink captions in a TagCloudLinkField object are displayed. "), Category("Data")]
        public string DataTextFormatString
        {
            get { return this.dataTextFormatString; }
            set
            {
                if (this.dataTextFormatString != value)
                {
                    this.dataTextFormatString = value;
                    if ((this as IStateManager).IsTrackingViewState)
                    {
                        this.dirtyFlags = this.dirtyFlags | DirtyFlags.DataTextFormatString;
                    }
                    this.OnFieldChanged();
                }
            }
        }

        /// <summary>
        /// Gets or sets the name of the field from the data source containing the 
        /// url for the hyperlink in the TagCloudLinkField object. 
        /// </summary>
        /// <value>The name of the field from the data source containing the 
        /// url for the hyperlink.</value>
        [DefaultValue(null), Description("The name of the field from the data source containing the url for the hyperlink in the TagCloudLinkField object."), Category("Data")]
        public string DataUrlField
        {
            get { return this.dataUrlField; }
            set
            {
                if (this.dataUrlField != value)
                {
                    this.dataUrlField = value;
                    if ((this as IStateManager).IsTrackingViewState)
                    {
                        this.dirtyFlags = this.dirtyFlags | DirtyFlags.DataUrlField;
                    }
                    this.OnFieldChanged();
                }
            }
        }

        /// <summary>
        /// Get or sets the string that specifies the format in which the hyperlink 
        /// urls in a TagCloudLinkField object are displayed. 
        /// </summary>
        /// <value>The string that specifies the format in which the hyperlink 
        /// urls.</value>
        [DefaultValue(null), Description("The string that specifies the format in which the hyperlink urls in a TagCloudLinkField object are displayed."), Category("Data")]
        public string DataUrlFormatString
        {
            get { return this.dataUrlFormatString; }
            set
            {
                if (this.dataUrlFormatString != value)
                {
                    this.dataUrlFormatString = value;
                    if ((this as IStateManager).IsTrackingViewState)
                    {
                        this.dirtyFlags = this.dirtyFlags | DirtyFlags.DataUrlFormatString;
                    }
                    this.OnFieldChanged();
                }
            }
        }

        /// <summary>
        /// Gets or sets the target window or frame in which to display the Web page 
        /// linked to when a hyperlink in a TagCloudLinkField object is clicked. 
        /// </summary>
        /// <value>The target window or frame in which to display the Web page 
        /// linked.</value>
        [TypeConverter(typeof(TargetConverter)), DefaultValue(null), Category("Behavior"), Description("The target window or frame in which to display the Web page linked to when a hyperlink in a TagCloudLinkField object is clicked. ")]
        public virtual string Target
        {
            get { return this.target; }
            set
            {
                if (this.target != value)
                {
                    this.target = value;
                    if ((this as IStateManager).IsTrackingViewState)
                    {
                        this.dirtyFlags = this.dirtyFlags | DirtyFlags.Target;
                    }
                    this.OnFieldChanged();
                }
            }
        }

        // Nested Types

        private enum DirtyFlags
        {
            None = 0,
            DataTextField = 1,
            DataTextFormatString = 2,
            DataUrlField = 4,
            DataUrlFormatString = 8,
            Target = 16,
            All = DataTextField + DataTextFormatString + DataUrlField + DataUrlFormatString + Target
        }

    }

    
    //public class HyperLinkField : DataControlField
    //{

    //    private void OnDataBindField(object sender, EventArgs e)
    //    {
    //        HyperLink link = (HyperLink) sender;
    //        Control namingContainer = link.NamingContainer;
    //        object component = null;
    //        if (namingContainer == null)
    //        {
    //            throw new HttpException(SR.GetString("DataControlField_NoContainer"));
    //        }
    //        component = DataBinder.GetDataItem(namingContainer);
    //        if ((component == null) && !base.DesignMode)
    //        {
    //            throw new HttpException(SR.GetString("DataItem_Not_Found"));
    //        }
    //        if ((this.textFieldDesc == null) && (this.urlFieldDescs == null))
    //        {
    //            PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(component);
    //            string dataTextField = this.DataTextField;
    //            if (dataTextField.Length != 0)
    //            {
    //                this.textFieldDesc = properties.Find(dataTextField, true);
    //                if ((this.textFieldDesc == null) && !base.DesignMode)
    //                {
    //                    throw new HttpException(SR.GetString("Field_Not_Found", new object[] { dataTextField }));
    //                }
    //            }
    //            string[] dataNavigateUrlFields = this.DataNavigateUrlFields;
    //            int num = dataNavigateUrlFields.Length;
    //            this.urlFieldDescs = new PropertyDescriptor[num];
    //            for (int i = 0; i < num; i++)
    //            {
    //                dataTextField = dataNavigateUrlFields[i];
    //                if (dataTextField.Length != 0)
    //                {
    //                    this.urlFieldDescs[i] = properties.Find(dataTextField, true);
    //                    if ((this.urlFieldDescs[i] == null) && !base.DesignMode)
    //                    {
    //                        throw new HttpException(SR.GetString("Field_Not_Found", new object[] { dataTextField }));
    //                    }
    //                }
    //            }
    //        }
    //        string str2 = string.Empty;
    //        if ((this.textFieldDesc != null) && (component != null))
    //        {
    //            object dataTextValue = this.textFieldDesc.GetValue(component);
    //            str2 = this.FormatDataTextValue(dataTextValue);
    //        }
    //        if ((base.DesignMode && (this.DataTextField.Length != 0)) && (str2.Length == 0))
    //        {
    //            str2 = SR.GetString("Sample_Databound_Text");
    //        }
    //        if (str2.Length > 0)
    //        {
    //            link.Text = str2;
    //        }
    //        int length = this.urlFieldDescs.Length;
    //        string str3 = string.Empty;
    //        if (((this.urlFieldDescs != null) && (length > 0)) && (component != null))
    //        {
    //            object[] dataUrlValues = new object[length];
    //            for (int j = 0; j < length; j++)
    //            {
    //                if (this.urlFieldDescs[j] != null)
    //                {
    //                    dataUrlValues[j] = this.urlFieldDescs[j].GetValue(component);
    //                }
    //            }
    //            string s = this.FormatDataNavigateUrlValue(dataUrlValues);
    //            if (!CrossSiteScriptingValidation.IsDangerousUrl(s))
    //            {
    //                str3 = s;
    //            }
    //        }
    //        if ((base.DesignMode && (this.DataNavigateUrlFields.Length != 0)) && (str3.Length == 0))
    //        {
    //            str3 = "url";
    //        }
    //        if (str3.Length > 0)
    //        {
    //            link.NavigateUrl = str3;
    //        }
    //    }

    //}
 


}
